import { V2 } from './V2';
import { McSprite } from './McSprite';
//import begin

/**
 * 带onUpdate函数的McSprite
 */
export class McSpriteAni extends McSprite {
    protected completeHandler: Laya.Handler = null;
    protected completeClear: boolean = false;
    protected setRateInterval: number = -1; // 设置的帧率

    protected timeElapsed: number = 0;
    protected speed: number = 1;
    public ispause: boolean = false;
    public iscomplete: boolean = false;//是否播放完毕
    private looponce: boolean = false;
    private islastframe: boolean = false;

    constructor(pos: V2 = V2.ZERO, zOrder: number = 0, completeHandler: Laya.Handler = null, completeClear: boolean = true) {
        super(pos, zOrder);

        this.completeHandler = completeHandler;
        this.completeClear = completeClear;
    }

    public clear(): void {
        this.completeHandler && this.completeHandler.recover();
        this.completeHandler = null;
    }

    public destroy(): void {
        this.clear();

        super.destroy();
    }

    public onUpdate(): void {
        if (!this.mcData) {
            return;
        }

        if (this.iscomplete || this.ispause) {
            return;
        }

        if (!this.loop && this.looponce) {
            this.looponce = false;
            this.iscomplete = true;
            if (this.completeHandler != null) {
                this.completeHandler.run();
            }
            if (this.completeClear) {
                this.graphics = null;
            }
            return;
        }

        this.timeElapsed += this.getTimeDelta() * this.speed;
        let interval = this.setRateInterval > 0 ? this.setRateInterval : this.rateInterval;
        while (this.timeElapsed > interval) {
            this.timeElapsed -= interval;
            this.gotoNextFrame();
        }
    }

    protected getTimeDelta(): number {
        return Laya.timer.delta / 1000;
    }

    /**
     * @param url 
     * @param loop 
     * @param force  是否强制渲染. 在对象使用池的时候 如果循环播放  必须在这里设置true 否则会return
     */
    public play(url: string, loop: boolean = false, force?: boolean, speed: number = 1, setRateInterval: number = -1): boolean {
        if (url == this.url && loop && !force) {
            return false;
        }

        this.timeElapsed = 0;
        this.currentFrameIdx = 0;
        this.iscomplete = false;
        this.speed = speed;
        this.setRateInterval = setRateInterval;
        this.looponce = false;
        this.islastframe = false;

        let result: boolean = super.play(url, loop, force);
        return result;
    }

    protected initGraphics(): void {
        if (this.islastframe) {
            this.gotoLastFrame()
        }
        else {
            this.gotoFrame(this.currentFrameIdx);
        }
    }

    public stop(frame: number = -1): void {
        this.iscomplete = true;
        this.gotoFrame(frame);
    }

    public start(): void {
        this.iscomplete = false;
    }

    public pause(): void {
        this.ispause = true;
    }

    public resume(): void {
        this.ispause = false;
    }

    public setCompleteHandler(value: Laya.Handler): void {
        this.completeHandler = value;
    }

    protected gotoNextFrame(): void {
        if (this.frameCount > 0) {
            this.currentFrameIdx = this.currentFrameIdx + 1;

            if (this.currentFrameIdx >= this.frameCount) {
                this.looponce = true;
                if (this.loop)
                    this.currentFrameIdx = 0;
                else
                    this.currentFrameIdx = this.frameCount - 1;
            }

        } else {
            this.currentFrameIdx = 0;
        }

        this.gotoFrame(this.currentFrameIdx);
    }

    public gotoLastFrame(calComplete: boolean = false): void {
        this.islastframe = true;
        if (!this.mcData) {
            return;
        }

        this.currentFrameIdx = this.frameCount > 0 ? this.frameCount - 1 : 0;
        this.gotoFrame(this.currentFrameIdx);

        if (!this.loop && !calComplete) {
            this.iscomplete = true;
        }
    }

    public getCurrentFrameIdx(): number {
        return this.currentFrameIdx;
    }
}